package utils

import (
	"archive/zip"
	"fmt"
	"gsc/types"
	"io"
	"os"
	"path/filepath"
	"strings"
)

func CreateFileAndWrite(file string, data []byte) {
	f, e := os.Create(file)
	if e != nil {
		fmt.Println("创建文件失败")
		return
	}
	defer f.Close()
	f.Write(data)
}

func Unzip(zipFile string, dest string) {
	// 打开ZIP文件
	r, err := zip.OpenReader(zipFile)
	if err != nil {
		fmt.Printf("打开ZIP文件失败: %v\n", err)
		return
	}
	defer r.Close()

	// 遍历ZIP文件中的所有文件
	for _, f := range r.File {
		rc, err := f.Open()
		if err != nil {
			fmt.Printf("打开文件失败: %v\n", err)
			continue
		}
		defer rc.Close()

		// 构建解压后的文件路径
		path := filepath.Join(dest, f.Name)

		// 检查路径是否安全（在目标目录内）
		if !strings.HasPrefix(path, filepath.Clean(dest)+string(os.PathSeparator)) {
			fmt.Printf("不安全的解压路径: %s\n", path)
			continue
		}

		// 创建文件所在的目录
		if f.FileInfo().IsDir() {
			os.MkdirAll(path, os.ModePerm)
		} else {
			os.MkdirAll(filepath.Dir(path), os.ModePerm)
			// 创建文件
			destFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
			if err != nil {
				fmt.Printf("创建文件失败: %v\n", err)
				continue
			}
			defer destFile.Close()

			// 将文件内容从ZIP复制到新文件
			_, err = io.Copy(destFile, rc)
			if err != nil {
				fmt.Printf("写入文件失败: %v\n", err)
			}
		}
	}
}

func ReplaceFileContent(file string, replace string, rewrite string) {
	data, e := os.ReadFile(file)
	if e != nil {
		fmt.Println("读取文件失败")
		return
	}
	data = []byte(strings.ReplaceAll(string(data), replace, rewrite))
	e = os.WriteFile(file, data, os.ModePerm)
	if e != nil {
		fmt.Println("写入文件失败")
		return
	}
}

func WalkConfigTo(gzeroActios []types.UpdateFileAction, projectName string, prefix string) error {
	var e error
	for _, action := range gzeroActios {
		// action 包含 *Path *Actions *NewName
		if !strings.Contains(action.Path, "*") {
			newName := strings.ReplaceAll(action.NewName, "${projectname}", projectName)

			for _, item := range action.Actions {
				rewrite := strings.ReplaceAll(item.Rewrite, "${projectname}", projectName)

				// 修改文件内容
				ReplaceFileContent(prefix+"/"+projectName+"/"+action.Path, item.Replace, rewrite)
			}

			if action.Path != newName {
				// 修改文件名
				e = os.Rename(prefix+"/"+projectName+"/"+action.Path, prefix+"/"+projectName+"/"+newName)
				if e != nil {
					fmt.Println("修改文件名失败", e)
					return e
				}
			}
		} else {
			pattenPath := strings.ReplaceAll(action.Path, "*", "")

			filepath.Walk(prefix+"/"+projectName, func(path string, info os.FileInfo, err error) error {
				if !info.IsDir() && strings.Contains(info.Name(), pattenPath) {
					fmt.Println("path", path)
					for _, item := range action.Actions {
						rewrite := strings.ReplaceAll(item.Rewrite, "${projectname}", projectName)
						// 修改文件内容
						ReplaceFileContent(path, item.Replace, rewrite)
					}
				}
				return nil
			})
		}
	}

	return e
}
